package group.raber.saber.jdbc.query.executor;

import group.raber.saber.jdbc.*;
import group.raber.saber.jdbc.query.PaginationQuery;
import group.raber.saber.jdbc.query.PaginationQueryResult;
import group.raber.saber.jdbc.query.SqlPaginationHandler;
import group.raber.saber.kit.SQLKit;
import group.raber.saber.kit.StringKit;
import group.raber.saber.lang.DataBox;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 分页查询抽象实现层
 * Created by tisir<yangsong158@qq.com> on 2017-05-28
 */
public class PaginationQueryExecutorImpl implements PaginationQueryExecutor{
    protected Logger logger = LoggerFactory.getLogger(this.getClass());
    protected JdbcTemplate jdbcTemplate;
    protected SqlPaginationHandler paginationHandler = null;


    public PaginationQueryExecutorImpl(JdbcTemplate jdbcTemplate,SqlPaginationHandler paginationHandler) {
        this.jdbcTemplate = jdbcTemplate;
        this.paginationHandler = paginationHandler;
    }

    protected <T> List<T> queryDataBeanList(NamedParameterJdbcTemplate jdbcTemplate,PaginationQuery paginationQuery,Class<T> classType,Map<Integer,String> columnPropertyMap, Map<Integer,String> summaryColumnPropertyMap){
        String originalSql = paginationQuery.getQuery();  //原始SQL
        RowMapper<T> rowMapper = null;
        if(columnPropertyMap==null||columnPropertyMap.size()==0){
            rowMapper = new BeanPropertyRowMapper<T>(classType);
        }else{
            rowMapper = new BeanPropertyByMapRowMapper<T>(classType,columnPropertyMap);
        }
        String paginationSql = paginationHandler.queryListSql(originalSql,paginationQuery.getIndex(),paginationQuery.getSize());
        logger.debug("DATA-FORM-LIST-SQL:"+paginationSql);
        List<T> dataList = jdbcTemplate.query(paginationSql, paginationQuery.getParameterMap(), rowMapper);
        return dataList;
    }

    protected List<DataBox> queryDataBoxList(NamedParameterJdbcTemplate jdbcTemplate, PaginationQuery paginationQuery, Class<DataBox> classType,Map<Integer,String> columnPropertyMap, Map<Integer,String> summaryColumnPropertyMap) {
        String originalSql = paginationQuery.getQuery();  //原始SQL

        RowMapper<DataBox> rowMapper = null;
        if(columnPropertyMap==null||columnPropertyMap.size()==0){
            rowMapper = new DataBoxRowMapper(new DefaultNameConverter());
        }else{
            rowMapper = new DataBoxByMapRowMapper(columnPropertyMap);
        }

        String paginationSql = paginationHandler.queryListSql(originalSql,paginationQuery.getIndex(),paginationQuery.getSize());
        logger.debug("DATA-FORM-LIST-SQL:"+paginationSql);
        List<DataBox> dataList = jdbcTemplate.query(paginationSql, paginationQuery.getParameterMap(),rowMapper);
        return dataList;
    }

    @SuppressWarnings("unchecked")
    public <T> PaginationQueryResult<T> query(PaginationQuery paginationQuery,Class<T> classType,Map<Integer,String> columnPropertyMap, final Map<Integer,String> summaryColumnPropertyMap){
        PaginationQueryResult<T> result = new PaginationQueryResult<T>();

        NamedParameterJdbcTemplate npjt = new NamedParameterJdbcTemplate(jdbcTemplate);
        String originalSql = paginationQuery.getQuery();  //原始SQL
        String paginationSql = paginationHandler.queryListSql(originalSql,paginationQuery.getIndex(),paginationQuery.getSize());
        //这里特殊处理下DataBox和普通JavaBean
        List<T> dataList = null;
        if(classType.isAssignableFrom(DataBox.class)){
            dataList = (List<T>) queryDataBoxList(npjt,paginationQuery,DataBox.class,columnPropertyMap,summaryColumnPropertyMap); //查询出列表数据
        }else{
            dataList = queryDataBeanList(npjt,paginationQuery,classType,columnPropertyMap,summaryColumnPropertyMap);
        }

        //小计,合计类,重新再查
        StringBuffer wholeSummarySql = new StringBuffer("select count(1) as TOTAL_COUNT");
        StringBuffer summarySql = new StringBuffer("select count(1) as TOTAL_COUNT");

        StringBuffer summaryClause = new StringBuffer();
        Map<String, String> summaryExpression = paginationQuery.getSummarizesExpressions();
//        Map<String, String> summaryExpressions = MapKit.newHashMap();
        Iterator<String> iterator = summaryExpression.keySet().iterator();
        boolean existsSummary = false;
        boolean existsSummaryColumnMap = !(summaryColumnPropertyMap==null||summaryColumnPropertyMap.size()==0);
        while(iterator.hasNext()){
            existsSummary = true;
            String columnName = iterator.next();
            String expression = summaryExpression.get(columnName);
            expression = expression.replaceAll("\\$\\{COLUMN\\}",columnName);
            if(existsSummaryColumnMap){
                summaryClause.append(",").append(expression);
            }else{
                summaryClause.append(",").append(expression).append(" AS ").append(columnName);
            }
        }
        if(existsSummary&&summaryClause.charAt(0)==','){
            summaryClause.deleteCharAt(0);
        }
        if(existsSummary&&!StringKit.isBlank(summaryClause)){
            if(paginationQuery.isWholeSummary()){
                wholeSummarySql.append(",").append(summaryClause);
            }
            if(paginationQuery.isSummary()){
                summarySql.append(",").append(summaryClause);
            }
        }
        wholeSummarySql.append(" FROM (").append(originalSql).append(") V_WHOLE_SUMMARY");//总计全部
        summarySql.append(" FROM (").append(paginationSql).append(") V_SUMMARY");  //小计当前页


        result.setDataList(dataList);
        result.setSize(paginationQuery.getSize());
        result.setIndex(paginationQuery.getIndex());
        result.setRows(dataList.size());

        //统计部分的rowMapper
        RowMapper<DataBox> rowMapper = null;
        if(existsSummaryColumnMap){
            rowMapper = new RowMapper<DataBox>(){
                public DataBox mapRow(ResultSet rs, int rowNum) throws SQLException {
                    return SQLKit.getRowValue(rs,summaryColumnPropertyMap);
                }
            };
        }else{
            rowMapper = new RowMapper<DataBox>(){
                public DataBox mapRow(ResultSet rs, int rowNum) throws SQLException {
                    return SQLKit.getRowValue(rs,new DefaultNameConverter());
                }
            };
        }

        //处理合计部分
        DataBox wholeSummaryRow = npjt.queryForObject(wholeSummarySql.toString(),paginationQuery.getParameterMap(),rowMapper);
        result.setWholeRows(wholeSummaryRow.xGet("totalCount").intValue());
        wholeSummaryRow.remove("totalCount");
        result.setWholeSummarizes(wholeSummaryRow);

        //处理小计部分
        if(existsSummary){
            DataBox summaryRow = npjt.queryForObject(summarySql.toString(),paginationQuery.getParameterMap(),rowMapper);
            summaryRow.remove("totalCount");
            result.setSummarizes(summaryRow);
        }
        if(result.getSize()<=0){
            result.setPages(1);
        }else{
            result.setPages(result.getWholeRows()/result.getSize()+1);
        }

        return result;
    }
}
